package com.ruoyi.net.netconf.util;

import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.net.netconf.Device;
import com.ruoyi.net.netconf.NetconfException;
import com.ruoyi.net.netconf.NetconfSession;
import com.ruoyi.net.netconf.XML;
import com.ruoyi.net.netconf.examples.CreateDevice;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.xml.sax.SAXException;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 设备连接管理器
 */
@Component
public class DeviceManager {
    protected final Logger logger = LoggerFactory.getLogger(this.getClass());

    private Map<String, Device> deviceMap = new HashMap<String, Device>();

    /**
     * net mgmt ip
     */
    private String ip = "10.20.1.44";

    private Device device;

    /**
     * 获取设备连接
     *
     * @param ip
     * @return
     */
    public Device getDevice(String ip) {
        Device device = deviceMap.get(ip);
        if (device == null || !device.isConnected()) {
            try {
                device = CreateDevice.createDevice(ip, "", "");
                device.connect();
                // add
                deviceMap.put(ip, device);
            } catch (NetconfException e) {
                logger.error("getDevice获取设备连接异常：", e);
//                throw new RuntimeException(e);
            }
        }

        this.ip = ip;
        this.device = device;
        return device;
    }

    /**
     * 获取设备状态
     *
     * @param xml
     * @return
     */
    public String getStatus(String xml) {
        String returnStatus = "";
        try {
            XML rpc_reply = device.getRunningConfigAndState(xml);
            returnStatus = rpc_reply.toString();
        } catch (Exception e) {
            logger.error("getStatus获取设备状态异常：", e);
        }
        return returnStatus;
    }

    /**
     * 获取设备配置
     *
     * @param xml
     * @return
     */
    public String getConfig(String xml) {
        String returnConfig = "";
        try {
            XML rpc_reply = device.getRunningConfig(xml); //.getCandidateConfig(xml);
            returnConfig = rpc_reply.toString();
        } catch (Exception e) {
            logger.error("getConfig获取设备配置异常：", e);
        }
        return returnConfig;
    }

    /**
     * 下发配置
     *
     * @param xml
     * @param loadType
     * @return
     */
    public boolean editConfig(String xml, String loadType) {
        boolean isSend = true;
        loadType = StringUtils.isEmpty(loadType) ? "merge" : loadType;
        try {
            /*boolean isLocked = device.lockConfig();
            if (!isLocked) {
                device.lockConfig();
            }*/
            device.loadXMLConfiguration(xml, loadType);
            device.commit();
//            device.unlockConfig();
        } catch (Exception e) {
            isSend = false;
            logger.error("editConfig下发配置异常：", e);
            throw new ServiceException(e.getMessage());
        }
        return isSend;
    }

    /**
     * 判断设备是否连接
     *
     * @param ip
     * @return
     */
    public boolean isConnect(String ip) {
        Device device = deviceMap.get(ip);
        if (device == null) {
            return false;
        }

        return device.isConnected();
    }


    /**
     * 关闭设备连接
     *
     * @param ip
     */
    public void closeDevice(String ip) {
        Device device = deviceMap.get(ip);
        if (device != null) {
            device.close();
            deviceMap.remove(ip);
        }
    }

    /**
     * 执行rpc
     * @param xml
     * @return
     */
    public boolean executeRPC(String xml) {
        boolean isSend = true;
        try {
            /*boolean isLocked = device.lockConfig();
            if (!isLocked) {
                device.lockConfig();
            }*/
            XML rpcReply = device.executeRPC(xml);
            device.commit();
//            device.unlockConfig();
        } catch (Exception e) {
            isSend = false;
            logger.error("rpc下发配置异常：", e);
            throw new ServiceException(e.getMessage());
        }
        return isSend;
    }
}